import 'dart:io';
import 'dart:async';
import 'dart:math' as math;
import 'package:flutter/foundation.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:photo_manager/photo_manager.dart';
import '../riverpod/photo_backup_notifier.dart' as notifier;
import 'directory_cache_service.dart';
import 'upload/chunk_upload_service.dart';
import '../models/chunk_upload.dart';
import 'asset_cache_service.dart';
import 'backup/backup_deduplication_service.dart';
import 'file_hash_deduplication_service.dart';
import 'upload/core/upload_progress_service.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'dart:convert';
import '../config/app_config.dart';
import '../config/config_loader.dart';
import '../config/upload_config.dart';
import 'package:http/http.dart' as http;
import '../models/asset_backup_status.dart';
import '../services/upload/core/upload_task_manager.dart';
import '../services/upload/utils/directory_path_parser.dart';

/// 资产备份状态
enum AssetBackupStatus {
  pending, // 等待上传
  uploading, // 上传中
  completed, // 已完成
  failed, // 失败
}

/// 照片备份服务，用于处理自动备份功能
class PhotoBackupService {
  // 单例模式
  static final PhotoBackupService _instance = PhotoBackupService._internal();
  factory PhotoBackupService() => _instance;
  PhotoBackupService._internal();

  // 服务依赖
  final DirectoryCacheService _directoryCacheService = DirectoryCacheService();
  final AssetCacheService _assetCacheService = AssetCacheService();
  final ChunkUploadService _chunkUploadService = ChunkUploadService();
  final BackupDeduplicationService _firstLayerDeduplicationService =
      BackupDeduplicationService();
  final FileHashDeduplicationService _hashDeduplicationService =
      FileHashDeduplicationService();
  final UploadProgressService _progressService = UploadProgressService();
  final _uploadTaskManager = UploadTaskManager();
  final _directoryPathParser = DirectoryPathParser();

  // 备份状态
  bool _isBackingUp = false;
  int _currentParallelUploads = 0;
  final Set<String> _processingAssets = {};
  final Set<String> _processingFilePaths = {};
  final Set<String> _processedFilePaths = {};
  final List<AssetEntity> _pendingFilesForUpload = [];

  // 待上传资产队列
  final List<AssetEntity> _uploadQueue = [];

  // 当前正在处理的相册信息
  AssetPathEntity? _currentAlbum;
  String? _currentAlbumName;
  int _currentAlbumProcessedCount = 0;
  int _currentAlbumTotalCount = 0;

  // 待上传文件队列目标大小
  final int _targetPendingSize = 20;
  final int _minPendingSize = 15;
  final int _loadBatchSize = 10;

  // 设备名称
  String _deviceModel = '';

  // 上传速率相关
  final Map<String, double> _uploadSpeeds = {};
  final Map<String, int> _uploadStartTimes = {};

  // 任务ID到资产ID的映射关系
  final Map<String, String> _taskToAssetMap = {};

  /// 设置设备名称
  void setDeviceModel(String deviceModel) {
    _deviceModel = deviceModel;
  }

  /// 获取当前设备名称
  String get deviceModel => _deviceModel;

  /// 获取正在进行的备份任务数
  int get currentParallelUploads => _currentParallelUploads;

  /// 检查自动备份是否已开启
  bool isAutoBackupEnabled(notifier.PhotoBackupState state) {
    return (state.autoBackupPhotos || state.autoBackupVideos) &&
        state.selectedAlbums.values.any((selected) => selected);
  }

  /// 获取待备份的资产列表
  Future<List<AssetEntity>> getPendingBackupAssets(
    WidgetRef ref, {
    int limit = 20,
  }) async {
    debugPrint('开始获取待备份资产...');

    // 如果上传队列不为空，直接返回队列中的资产
    if (_uploadQueue.isNotEmpty) {
      debugPrint('直接返回上传队列中的${_uploadQueue.length}个资产');

      // 如果上传队列中的资产数量低于目标值，尝试加载更多
      if (_uploadQueue.length < _targetPendingSize) {
        _initializeLoadingIfNeeded(ref);
      }

      // 返回队列中的资产（不超过请求的数量）
      final resultCount = math.min(limit, _uploadQueue.length);
      return _uploadQueue.sublist(0, resultCount);
    }

    // 如果队列为空，初始化资产加载并应用文件路径过滤
    final loadedAssets = await initializeAssetLoading(ref);

    // 如果仍然无法加载到资产，尝试强制重新加载一次
    if (loadedAssets.isEmpty) {
      debugPrint('无法加载资产，尝试强制重新加载...');
      _resetCurrentAlbumState(); // 重置当前相册状态
      final forcedLoadedAssets = await initializeAssetLoading(ref);

      if (forcedLoadedAssets.isNotEmpty) {
        debugPrint('强制重新加载成功，获取到${forcedLoadedAssets.length}个资产');
        return forcedLoadedAssets;
      } else {
        debugPrint('强制重新加载仍未获取到资产，尝试直接从相册加载');

        // 尝试直接从相册获取资产作为最后手段
        try {
          final allAlbums = await PhotoManager.getAssetPathList(
            onlyAll: true,
            filterOption: FilterOptionGroup(
              imageOption: const FilterOption(
                sizeConstraint: SizeConstraint(minWidth: 0, minHeight: 0),
              ),
              createTimeCond: DateTimeCond(
                min: DateTime.now().subtract(
                  const Duration(days: 365 * 5),
                ), // 最近5年
                max: DateTime.now(),
              ),
            ),
          );

          if (allAlbums.isNotEmpty) {
            final recentAlbum = allAlbums.first;
            final recentAssets = await recentAlbum.getAssetListRange(
              start: 0,
              end: limit,
            );

            debugPrint('直接从相册获取到${recentAssets.length}个资产');
            return recentAssets;
          }
        } catch (e) {
          debugPrint('直接从相册获取资产失败: $e');
        }
      }
    }

    if (loadedAssets.isNotEmpty) {
      // 应用文件路径过滤，但确保即使都被过滤也返回至少一个资产
      final filteredAssets = await _filterByFilePath(loadedAssets);
      if (filteredAssets.isNotEmpty) {
        return filteredAssets;
      } else {
        debugPrint('所有资产都被过滤，返回原始资产的第一个');
        return [loadedAssets.first]; // 至少返回一个资产
      }
    }

    return [];
  }

  /// 按文件路径过滤资产，确保不重复处理相同文件
  Future<List<AssetEntity>> _filterByFilePath(List<AssetEntity> assets) async {
    if (assets.isEmpty) return [];

    debugPrint('按文件路径过滤${assets.length}个资产');

    final List<AssetEntity> filteredAssets = [];
    final Set<String> pathsInBatch = {};

    for (final asset in assets) {
      try {
        // 获取文件
        final file = await asset.file;
        if (file == null) {
          debugPrint('无法获取资产${asset.id}对应的文件，跳过');
          continue;
        }

        final filePath = file.path;

        // 检查文件路径是否已在处理中、已处理或当前批次中重复
        if (_processingFilePaths.contains(filePath) ||
            _processedFilePaths.contains(filePath) ||
            pathsInBatch.contains(filePath)) {
          debugPrint('文件路径已存在，跳过: $filePath');
          continue;
        }

        // 添加到当前批次路径集合
        pathsInBatch.add(filePath);
        filteredAssets.add(asset);
      } catch (e) {
        debugPrint('过滤资产${asset.id}时发生错误: $e');
        // 出错时保留资产，让正常上传流程去处理
        filteredAssets.add(asset);
      }
    }

    debugPrint('文件路径过滤后剩余${filteredAssets.length}个资产');
    return filteredAssets;
  }

  // 如果需要初始化加载
  Future<void> _initializeLoadingIfNeeded(WidgetRef ref) async {
    // 如果当前没有活动的相册，初始化加载
    if (_currentAlbum == null || _uploadQueue.isEmpty) {
      debugPrint('初始化资产加载...');
      await initializeAssetLoading(ref);
    }
  }

  /// 更新原有的startBatchUpload方法，使用新的按需加载机制
  Future<void> startBatchUpload(WidgetRef ref, List<AssetEntity> assets) async {
    if (assets.isEmpty) return;

    // 先清理队列，避免重复添加
    _uploadQueue.clear();

    debugPrint('启动批量上传，添加${assets.length}个资产到上传队列');

    // 确保多层去重服务已初始化
    if (!_hashDeduplicationService.isInitialized) {
      await _hashDeduplicationService.initialize();
    }

    // 获取当前批量上传的最大并行数
    final backupState = ref.read(notifier.photoBackupProvider);
    final maxParallel = backupState.parallelBackupCount;

    // 设置上传状态
    _isBackingUp = true;

    // 将资产添加到上传队列，确保不重复添加
    for (var asset in assets) {
      if (!_processingAssets.contains(asset.id) &&
          !_uploadQueue.any((queuedAsset) => queuedAsset.id == asset.id)) {
        _uploadQueue.add(asset);
      }
    }

    // 处理上传队列
    _processUploadQueue(maxParallel);
  }

  /// 处理上传队列
  Future<void> _processUploadQueue(int maxParallel) async {
    debugPrint(
      '处理上传队列: 队列长度=${_uploadQueue.length}, 当前并行上传数=$_currentParallelUploads, 最大并行=$maxParallel',
    );

    if (_uploadQueue.isEmpty) {
      debugPrint('上传队列为空，无需处理');
      return;
    }

    // 检查是否达到最大并行数
    if (_currentParallelUploads >= maxParallel) {
      debugPrint('已达到最大并行上传数限制: $_currentParallelUploads/$maxParallel');
      return;
    }

    // 执行文件路径预检查，移除重复文件
    await _preprocessUploadQueue();

    // 计算可以启动的上传任务数
    int availableSlots = maxParallel - _currentParallelUploads;
    int tasksToStart = math.min(availableSlots, _uploadQueue.length);

    if (tasksToStart <= 0) {
      debugPrint('没有可启动的上传任务');
      return;
    }

    debugPrint('可启动$tasksToStart个上传任务');

    for (int i = 0; i < tasksToStart; i++) {
      if (_uploadQueue.isEmpty) break;

      final asset = _uploadQueue.removeAt(0);
      _currentParallelUploads++;

      debugPrint(
        '启动资产${asset.id}的上传任务，当前并行数: $_currentParallelUploads/$maxParallel',
      );

      // 异步上传文件，传递onAssetProcessed回调
      _uploadAsset(
        asset,
        onAssetProcessed: (processedAsset, success) async {
          _currentParallelUploads--;
          debugPrint(
            '资产${processedAsset.id}上传${success ? "成功" : "失败"}，当前并行数: $_currentParallelUploads',
          );

          // 处理下一个
          if (_uploadQueue.isNotEmpty) {
            _processUploadQueue(maxParallel);
          } else if (_currentParallelUploads == 0) {
            _isBackingUp = false;
            debugPrint('所有上传任务已完成，上传状态已重置');
          }
        },
      ).catchError((e) {
        debugPrint('上传资产${asset.id}异常: $e');
        _currentParallelUploads--;
        _processingAssets.remove(asset.id);

        // 处理下一个
        if (_uploadQueue.isNotEmpty) {
          _processUploadQueue(maxParallel);
        } else if (_currentParallelUploads == 0) {
          _isBackingUp = false;
          debugPrint('所有上传任务已完成(包含异常)，上传状态已重置');
        }
      });
    }
  }

  /// 预处理上传队列，移除重复文件
  Future<void> _preprocessUploadQueue() async {
    if (_uploadQueue.isEmpty) return;

    debugPrint('预处理上传队列，移除重复文件，原始队列长度: ${_uploadQueue.length}');

    final Set<String> queuedFilePaths = {};
    final List<AssetEntity> uniqueAssets = [];

    // 遍历上传队列，进行文件路径检查
    for (int i = 0; i < _uploadQueue.length; i++) {
      final asset = _uploadQueue[i];

      try {
        // 获取文件
        final file = await asset.file;
        if (file == null) {
          debugPrint('无法获取资产${asset.id}对应的文件，将从队列移除');
          continue;
        }

        final filePath = file.path;

        // 检查文件路径是否已在处理中或已处理
        if (_processingFilePaths.contains(filePath)) {
          debugPrint('文件已在处理中，从队列移除: $filePath');

          // 标记为已处理
          _processingAssets.remove(asset.id);
          continue;
        }

        if (_processedFilePaths.contains(filePath)) {
          debugPrint('文件已在本次会话中处理过，从队列移除: $filePath');

          // 标记为已处理
          _processingAssets.remove(asset.id);
          continue;
        }

        // 检查是否与当前队列中其他文件重复
        if (queuedFilePaths.contains(filePath)) {
          debugPrint('文件路径在当前处理队列中重复，从队列移除: $filePath');
          continue;
        }

        // 将文件路径添加到已检查集合
        queuedFilePaths.add(filePath);
        uniqueAssets.add(asset);
      } catch (e) {
        debugPrint('预处理资产${asset.id}时发生错误: $e');
        // 出错时保留资产，让正常上传流程去处理错误
        uniqueAssets.add(asset);
      }
    }

    // 更新上传队列
    _uploadQueue.clear();
    _uploadQueue.addAll(uniqueAssets);

    debugPrint('预处理完成，去重后队列长度: ${_uploadQueue.length}');
  }

  /// 添加新资产到上传队列
  Future<void> addNewAssetsToQueue(WidgetRef ref, int count) async {
    if (!_isBackingUp || count <= 0) return;

    debugPrint('尝试添加$count个新资产到上传队列，当前处理中: ${_processingAssets.length}个');

    try {
      // 获取新的待备份资产
      final newAssets = await getPendingBackupAssets(ref, limit: count);

      if (newAssets.isEmpty) {
        debugPrint('没有找到新的待备份资产');
        return;
      }

      // 过滤掉已经在处理中的资产
      final filteredAssets =
          newAssets
              .where((asset) => !_processingAssets.contains(asset.id))
              .toList();

      if (filteredAssets.isEmpty) {
        debugPrint('所有待备份资产都已在处理中');
        return;
      }

      debugPrint('找到${filteredAssets.length}个新资产，添加到上传队列');

      // 添加到上传队列
      for (var asset in filteredAssets) {
        _uploadQueue.add(asset);
        _processingAssets.add(asset.id);
      }

      // 获取当前批量上传的最大并行数
      final backupState = ref.read(notifier.photoBackupProvider);
      final maxParallel = backupState.parallelBackupCount;

      // 处理上传队列
      if (_currentParallelUploads < maxParallel) {
        _processUploadQueue(maxParallel);
      }
    } catch (e) {
      debugPrint('添加新资产到上传队列失败: $e');
    }
  }

  /// 获取相册信息
  Future<notifier.AlbumInfo?> _getAlbumName(AssetEntity asset) async {
    try {
      debugPrint('获取资产${asset.id}所属相册信息...');

      // 获取所有相册
      final albums = await PhotoManager.getAssetPathList(onlyAll: false);
      debugPrint('找到${albums.length}个相册');

      // 查找包含该资产的相册
      for (final album in albums) {
        // 使用更高效的查询方式，检查资产是否在此相册中
        final assetList = await album.getAssetListRange(start: 0, end: 100);
        if (assetList.any((a) => a.id == asset.id)) {
          debugPrint('找到资产${asset.id}所属相册: ${album.name} (ID: ${album.id})');
          return notifier.AlbumInfo(id: album.id, name: album.name);
        }
      }

      // 如果未找到相册，尝试通过ID前缀查找
      final albumId = asset.id.split('/').first;
      debugPrint('未找到资产${asset.id}所属相册，使用ID前缀[$albumId]作为相册ID');
      return notifier.AlbumInfo(id: albumId, name: '默认相册');
    } catch (e) {
      debugPrint('获取相册信息失败: $e');
      // 返回默认相册信息
      final albumId = asset.id.split('/').first;
      return notifier.AlbumInfo(id: albumId, name: '默认相册');
    }
  }

  /// 监控上传进度并计算速度
  void _monitorUploadProgress(String assetId) {
    // 创建定时器，定期检查上传任务状态
    Timer.periodic(const Duration(seconds: 1), (timer) {
      // 任务列表为空时，停止监控
      if (ChunkUploadService.uploadTasks.isEmpty) {
        timer.cancel();
        _uploadSpeeds.remove(assetId);
        return;
      }

      // 尝试查找对应的上传任务
      UploadTask? task;
      try {
        task = ChunkUploadService.uploadTasks.firstWhere(
          (task) =>
              task.status == UploadTaskStatus.uploading ||
              task.status == UploadTaskStatus.pending,
        );
      } catch (e) {
        // 如果没有找到正在上传或等待的任务，则使用第一个任务
        if (ChunkUploadService.uploadTasks.isNotEmpty) {
          task = ChunkUploadService.uploadTasks.first;
        }
      }

      // 任务为空或已完成或失败，停止监控
      if (task == null ||
          task.status == UploadTaskStatus.completed ||
          task.status == UploadTaskStatus.failed ||
          task.status == UploadTaskStatus.canceled) {
        timer.cancel();
        _uploadSpeeds.remove(assetId);
        return;
      }

      // 计算上传速度 (字节/秒)
      if (task.uploadedBytes > 0 && _uploadStartTimes.containsKey(assetId)) {
        final startTime = _uploadStartTimes[assetId]!;
        final now = DateTime.now().millisecondsSinceEpoch;
        final elapsedSeconds = (now - startTime) / 1000;

        if (elapsedSeconds > 0) {
          final speed = task.uploadedBytes / elapsedSeconds;
          _uploadSpeeds[assetId] = speed;
        }
      }
    });
  }

  /// 获取资产的上传速度 (字节/秒)
  double getAssetUploadSpeed(String assetId) {
    return _uploadSpeeds[assetId] ?? 0.0;
  }

  /// 格式化上传速度
  String formatUploadSpeed(double speed) {
    if (speed < 1024) return '${speed.toStringAsFixed(1)} B/s';
    if (speed < 1024 * 1024) return '${(speed / 1024).toStringAsFixed(1)} KB/s';
    return '${(speed / (1024 * 1024)).toStringAsFixed(1)} MB/s';
  }

  /// 根据任务ID获取资产ID
  String? getAssetIdByTaskId(String taskId) {
    return _taskToAssetMap[taskId];
  }

  /// 判断资产是否正在上传
  bool isAssetUploading(String assetId) {
    return _processingAssets.contains(assetId);
  }

  /// 判断是否有正在进行的备份任务
  bool get isBackingUp => _isBackingUp;

  /// 更新资产备份状态
  void _updateAssetStatus(AssetEntity asset, AssetBackupStatus status) {
    // 这里可以添加状态更新逻辑
    debugPrint('资产 ${asset.id} 状态更新为: $status');
  }

  /// 更新资产上传进度
  void _updateAssetProgress(AssetEntity asset, double progress) {
    // 这里可以添加进度更新逻辑
    debugPrint('资产 ${asset.id} 上传进度: ${(progress * 100).toStringAsFixed(1)}%');
  }

  /// 开始下一个上传任务
  void _startNextUpload(int maxParallel) {
    if (_uploadQueue.isEmpty || _currentParallelUploads >= maxParallel) {
      return;
    }

    final asset = _uploadQueue.removeAt(0);
    _currentParallelUploads++;

    // 异步上传文件
    _uploadAsset(asset)
        .then((_) {
          _currentParallelUploads--;
          _startNextUpload(maxParallel);
        })
        .catchError((e) {
          debugPrint('上传资产失败: $e');
          _currentParallelUploads--;
          _startNextUpload(maxParallel);
        });
  }

  /// 暂停所有上传任务
  void pauseAllUploads() {
    debugPrint('暂停所有上传任务');
    // 暂停所有正在上传的任务
    for (var task in ChunkUploadService.uploadTasks) {
      if (task.status == UploadTaskStatus.uploading ||
          task.status == UploadTaskStatus.pending) {
        ChunkUploadService.pauseUploadTask(task.id);
      }
    }
  }

  /// 恢复所有上传任务
  void resumeAllUploads() {
    debugPrint('恢复所有上传任务');
    // 恢复所有暂停的任务
    for (var task in ChunkUploadService.uploadTasks) {
      if (task.status == UploadTaskStatus.paused) {
        ChunkUploadService.resumeUploadTask(task.id);
      }
    }
  }

  /// 初始化服务并清理无效记录
  Future<void> initialize() async {
    debugPrint('正在初始化PhotoBackupService...');

    // 确保多层去重服务已初始化
    if (!_hashDeduplicationService.isInitialized) {
      await _hashDeduplicationService.initialize();
      debugPrint('已初始化多层去重服务');
    }

    // 清理所有"未知相册"的进度记录
    await _progressService.cleanupUnknownAlbums();
  }

  /// 获取进度服务实例（用于调试）
  UploadProgressService getProgressService() {
    return _progressService;
  }

  /// 重置备份状态（用于修复挂起的备份状态）
  void resetBackupStatus() {
    _isBackingUp = false;
    _currentParallelUploads = 0;
    debugPrint('已重置备份状态: _isBackingUp = false, _currentParallelUploads = 0');
  }

  /// 从相册中获取非重复资产的通用方法
  Future<List<AssetEntity>> _getNonDuplicateAssetsFromAlbum({
    required AssetPathEntity album,
    required String albumName,
    required int startIndex,
    int limit = 20,
    int maxBatchesToCheck = 5,
  }) async {
    final totalCount = await album.assetCountAsync;

    // 获取备份设置
    final autoBackupPhotos = true; // 默认值，实际应从设置中获取
    final autoBackupVideos = true; // 默认值，实际应从设置中获取

    // 如果已经处理完所有资产
    if (startIndex >= totalCount) {
      debugPrint('相册 $albumName 已处理完所有资产');
      return [];
    }

    // 计算要获取的资产数量，不超过剩余资产数量
    final fetchCount = math.min(
      limit * maxBatchesToCheck,
      totalCount - startIndex,
    );
    debugPrint(
      '从相册 $albumName 一次性获取 $fetchCount 个资产，从索引 $startIndex 开始，总数: $totalCount',
    );

    // 一次性获取所有需要的资产
    final assets = await album.getAssetListRange(
      start: startIndex,
      end: startIndex + fetchCount,
    );

    // 如果没有获取到资产，说明已经到达相册末尾
    if (assets.isEmpty) {
      debugPrint('相册 $albumName 已处理完所有资产');
      return [];
    }

    // 根据用户设置过滤照片和视频
    final filteredAssets =
        assets.where((asset) {
          if (asset.type == AssetType.image) {
            return autoBackupPhotos;
          } else if (asset.type == AssetType.video) {
            return autoBackupVideos;
          }
          return false;
        }).toList();

    debugPrint('从相册 $albumName 过滤后剩余 ${filteredAssets.length} 个资产');

    // 过滤掉已经在处理中的资产
    final newAssets =
        filteredAssets
            .where((asset) => !_processingAssets.contains(asset.id))
            .toList();

    // 应用多层去重逻辑，过滤掉已上传过的文件
    debugPrint('开始对${newAssets.length}个资产执行多层去重过滤');
    final nonDuplicates = await _hashDeduplicationService.filterDuplicateAssets(
      newAssets,
    );
    debugPrint('多层去重过滤后剩余${nonDuplicates.length}个资产需要上传');

    // 更新进度记录，标记这批资产已处理
    await _progressService.updateAlbumProgress(
      albumId: album.id,
      albumName: albumName,
      processedCount: startIndex + assets.length,
      lastAssetId: assets.isNotEmpty ? assets.last.id : null,
    );

    return nonDuplicates;
  }

  /// 初始化加载资产并设置回调
  Future<List<AssetEntity>> initializeAssetLoading(WidgetRef ref) async {
    debugPrint('初始化资产加载器');

    // 获取备份设置
    final backupState = ref.read(notifier.photoBackupProvider);
    final autoBackupPhotos = backupState.autoBackupPhotos;
    final autoBackupVideos = backupState.autoBackupVideos;

    // 检查自动备份设置
    if (!autoBackupPhotos && !autoBackupVideos) {
      debugPrint('自动备份未启用');
      return [];
    }

    // 查找待处理相册
    final albumInfo = await _findAlbumToProcess(ref);
    if (albumInfo == null) {
      debugPrint('没有找到待处理的相册');
      return [];
    }

    // 获取相册对象
    final album = await AssetPathEntity.fromId(albumInfo.id);
    if (album == null) {
      debugPrint('无法获取相册对象: ${albumInfo.name}');
      return [];
    }

    // 保存当前处理的相册信息
    _currentAlbum = album;
    _currentAlbumName = albumInfo.name;
    _currentAlbumProcessedCount = await _progressService.getAlbumProcessedCount(
      albumInfo.id,
    );
    _currentAlbumTotalCount = await album.assetCountAsync;

    debugPrint(
      '初始化处理相册: $_currentAlbumName, 已处理: $_currentAlbumProcessedCount, 总数: $_currentAlbumTotalCount',
    );

    // 加载初始批次资产
    return await _loadMoreAssets(autoBackupPhotos, autoBackupVideos);
  }

  /// 加载更多资产以保持队列在目标大小
  Future<List<AssetEntity>> _loadMoreAssets(
    bool includePhotos,
    bool includeVideos,
  ) async {
    // 验证当前相册是否有效
    if (_currentAlbum == null || _currentAlbumName == null) {
      debugPrint('没有活动的相册，无法加载更多资产');
      return [];
    }

    // 检查是否已处理完所有资产
    if (_currentAlbumProcessedCount >= _currentAlbumTotalCount) {
      debugPrint('相册 $_currentAlbumName 已处理完所有资产');
      await _progressService.markAlbumCompleted(_currentAlbum!.id);
      _resetCurrentAlbumState();
      return [];
    }

    // 计算要获取的资产数量，不超过剩余资产数量
    final fetchCount = math.min(
      _loadBatchSize,
      _currentAlbumTotalCount - _currentAlbumProcessedCount,
    );
    debugPrint(
      '从相册 $_currentAlbumName 加载 $fetchCount 个资产，从索引 $_currentAlbumProcessedCount 开始',
    );

    // 获取下一批资产
    final assets = await _currentAlbum!.getAssetListRange(
      start: _currentAlbumProcessedCount,
      end: _currentAlbumProcessedCount + fetchCount,
    );

    // 如果没有资产，标记相册已完成
    if (assets.isEmpty) {
      debugPrint('相册 $_currentAlbumName 已到达末尾');
      await _progressService.markAlbumCompleted(_currentAlbum!.id);
      _resetCurrentAlbumState();
      return [];
    }

    // 根据设置过滤照片和视频
    final filteredAssets =
        assets.where((asset) {
          if (asset.type == AssetType.image) {
            return includePhotos;
          } else if (asset.type == AssetType.video) {
            return includeVideos;
          }
          return false;
        }).toList();

    debugPrint('相册 $_currentAlbumName 过滤后剩余 ${filteredAssets.length} 个资产');

    // 过滤掉已经在处理中的资产
    final newAssets =
        filteredAssets
            .where((asset) => !_processingAssets.contains(asset.id))
            .toList();

    // 应用多层去重逻辑，过滤掉已上传过的文件
    final nonDuplicates = await _hashDeduplicationService.filterDuplicateAssets(
      newAssets,
    );
    debugPrint('找到 ${nonDuplicates.length} 个非重复资产可上传');

    // 更新进度记录
    await _progressService.updateAlbumProgress(
      albumId: _currentAlbum!.id,
      albumName: _currentAlbumName!,
      processedCount: _currentAlbumProcessedCount + assets.length,
      lastAssetId: assets.isNotEmpty ? assets.last.id : null,
    );

    // 更新当前处理位置
    _currentAlbumProcessedCount += assets.length;

    // 将新资产添加到上传队列
    _uploadQueue.addAll(nonDuplicates);

    return nonDuplicates;
  }

  /// 处理资产上传完成或检测为重复的回调
  Future<void> onAssetProcessed(AssetEntity asset, bool isSuccess) async {
    debugPrint('资产${asset.id}处理${isSuccess ? "成功" : "失败"}');

    // 从处理中的资产集合移除
    _processingAssets.remove(asset.id);

    // 尝试清理文件路径缓存
    try {
      final file = await asset.file;
      if (file != null) {
        // 如果成功，将路径移除处理中集合，添加到已处理集合
        if (isSuccess) {
          _processingFilePaths.remove(file.path);
          _processedFilePaths.add(file.path);
        } else {
          // 如果失败，仅从处理中集合移除
          _processingFilePaths.remove(file.path);
        }
      }
    } catch (e) {
      debugPrint('清理资产${asset.id}路径缓存时发生错误: $e');
    }

    // 检查上传队列大小，如果低于最小阈值就加载更多
    if (_uploadQueue.length < _minPendingSize) {
      debugPrint(
        '上传队列大小低于阈值($_minPendingSize)，当前: ${_uploadQueue.length}，加载更多资产',
      );

      // 获取备份设置
      final backupState = await _getBackupSettings();

      // 加载更多资产
      final newAssets = await _loadMoreAssets(
        backupState.autoBackupPhotos,
        backupState.autoBackupVideos,
      );

      // 过滤新加载的资产，确保文件路径不重复
      final filteredAssets = await _filterByFilePath(newAssets);

      // 添加到上传队列
      _uploadQueue.addAll(filteredAssets);

      if (newAssets.isEmpty && _uploadQueue.isEmpty) {
        debugPrint('没有更多资产可上传，当前相册处理完毕');
        // 如果当前相册已处理完，可以查找下一个相册
        await _findAndInitializeNextAlbum();
      }
    }
  }

  /// 重置当前相册状态
  void _resetCurrentAlbumState() {
    _currentAlbum = null;
    _currentAlbumName = null;
    _currentAlbumProcessedCount = 0;
    _currentAlbumTotalCount = 0;
  }

  /// 查找下一个待处理的相册并初始化
  Future<void> _findAndInitializeNextAlbum() async {
    // 这里需要实现查找下一个相册的逻辑
    // 可以重用之前的查找未完成相册或资产最多相册的代码
    debugPrint('正在查找下一个待处理相册...');
  }

  /// 查找待处理的相册
  Future<notifier.AlbumInfo?> _findAlbumToProcess(WidgetRef ref) async {
    // 获取备份设置
    final backupState = ref.read(notifier.photoBackupProvider);

    // 首先检查是否有未完成的相册
    final incompleteAlbums = await _progressService.getIncompleteAlbums();
    if (incompleteAlbums.isNotEmpty) {
      final progressRecord = incompleteAlbums.first;
      debugPrint('找到未完成的上传任务: ${progressRecord.albumName}');

      // 查找相册信息
      final albumInfo = backupState.albumCache.firstWhere(
        (album) => album.id == progressRecord.albumId,
        orElse: () => const notifier.AlbumInfo(id: '', name: ''),
      );

      if (albumInfo.id.isNotEmpty &&
          backupState.selectedAlbums[albumInfo.id] == true) {
        return albumInfo;
      } else {
        // 相册不在选择列表中，删除记录
        debugPrint('相册 ${progressRecord.albumName} 不再选中列表中，删除进度记录');
        await _progressService.deleteAlbumProgress(progressRecord.albumId);
        // 递归查找下一个
        return _findAlbumToProcess(ref);
      }
    }

    // 如果没有未完成的相册，查找资产最多的相册
    final selectedAlbumInfos =
        backupState.albumCache
            .where((album) => backupState.selectedAlbums[album.id] == true)
            .toList();

    if (selectedAlbumInfos.isEmpty) {
      debugPrint('没有选择任何相册');
      return null;
    }

    notifier.AlbumInfo? currentAlbum;
    int maxAssetCount = 0;

    for (var albumInfo in selectedAlbumInfos) {
      // 检查相册是否已完成
      final isCompleted = await _progressService.isAlbumCompleted(albumInfo.id);
      if (isCompleted) {
        debugPrint('相册 ${albumInfo.name} 已完成上传，跳过');
        continue;
      }

      final validCount = albumInfo.getValidCount(
        backupState.autoBackupPhotos,
        backupState.autoBackupVideos,
      );

      if (validCount > maxAssetCount) {
        maxAssetCount = validCount;
        currentAlbum = albumInfo;
      }
    }

    if (currentAlbum != null) {
      debugPrint('选择处理相册: ${currentAlbum.name}，预计资产数: $maxAssetCount');
    } else {
      debugPrint('没有找到合适的相册，所有相册可能都已完成上传');
    }

    return currentAlbum;
  }

  /// 获取当前备份设置（无需WidgetRef）
  Future<notifier.PhotoBackupState> _getBackupSettings() async {
    // 直接从存储加载备份设置
    final prefs = await SharedPreferences.getInstance();
    final stateJson = prefs.getString('photo_backup_state');
    if (stateJson != null) {
      try {
        final Map<String, dynamic> json = jsonDecode(stateJson);
        return notifier.PhotoBackupState.fromJson(json);
      } catch (e) {
        debugPrint('加载备份设置失败: $e');
      }
    }

    // 返回默认设置
    return notifier.PhotoBackupState(
      autoBackupPhotos: true,
      autoBackupVideos: true,
      albumCache: [],
      selectedAlbums: {},
    );
  }

  /// 上传单个资产
  Future<bool> _uploadAsset(
    AssetEntity asset, {
    Function(AssetEntity, bool)? onAssetProcessed,
  }) async {
    // 添加到处理中的资产集合
    _processingAssets.add(asset.id);

    try {
      // 获取详细资产信息
      final file = await asset.file;
      if (file == null) {
        debugPrint('无法获取文件: ${asset.id}');
        // 触发处理完成回调
        if (onAssetProcessed != null) {
          await onAssetProcessed(asset, false);
        }
        return false;
      }

      final filePath = file.path;

      // 减少内存使用，避免大量日志
      debugPrint(
        '处理资产: ${asset.id}, 文件大小: ${(file.lengthSync() / 1024).toStringAsFixed(2)} KB',
      );

      // 检查文件路径是否已在处理中或已处理
      if (_processingFilePaths.contains(filePath)) {
        debugPrint('文件已在处理中，跳过: $filePath');
        // 触发处理完成回调
        if (onAssetProcessed != null) {
          await onAssetProcessed(asset, true);
        }
        return true;
      }

      if (_processedFilePaths.contains(filePath)) {
        debugPrint('文件已在本次会话中处理过，跳过: $filePath');
        // 触发处理完成回调
        if (onAssetProcessed != null) {
          await onAssetProcessed(asset, true);
        }
        return true;
      }

      // 标记文件为正在处理
      _processingFilePaths.add(filePath);

      // 检查是否为重复文件（使用多层去重）
      bool isDuplicate = false;

      // 只检查较小文件的重复性，大文件直接上传
      if (file.lengthSync() < 50 * 1024 * 1024) {
        // 小于50MB的文件才检查重复
        try {
          isDuplicate = await _hashDeduplicationService.isAssetDuplicate(asset);
        } catch (e) {
          debugPrint('检查文件重复性失败: $e');
          isDuplicate = false;
        }
      }

      if (isDuplicate) {
        debugPrint('跳过重复文件: ${asset.id}');
        // 找到资产对应的相册
        try {
          // 获取资产的相册信息
          final albumInfo = await _getAlbumName(asset);
          if (albumInfo != null) {
            final albumId = albumInfo.id;
            final albumName = albumInfo.name;

            // 更新进度
            final currentCount = await _progressService.getAlbumProcessedCount(
              albumId,
            );
            await _progressService.updateAlbumProgress(
              albumId: albumId,
              albumName: albumName,
              processedCount: currentCount + 1,
              lastAssetId: null,
            );
          } else {
            debugPrint('无法确定资产 ${asset.id} 的相册信息，跳过进度更新');
          }
        } catch (e) {
          debugPrint('无法更新相册进度: $e');
        }

        // 上传成功后，保存文件哈希并添加到已处理集合
        await _hashDeduplicationService.saveUploadedFileHash(file);
        _processedFilePaths.add(filePath);

        // 从处理中文件集合移除
        _processingFilePaths.remove(filePath);

        // 触发处理完成回调
        if (onAssetProcessed != null) {
          await onAssetProcessed(asset, true);
        }

        return true; // 认为重复文件上传成功
      }

      debugPrint('开始上传资产: ${asset.id}');

      // 记录上传开始时间，用于计算速率
      _uploadStartTimes[asset.id] = DateTime.now().millisecondsSinceEpoch;

      // 处理设备名称为空的情况
      if (_deviceModel.isEmpty) {
        _deviceModel = Platform.isAndroid ? 'Android设备' : 'iOS设备';
        debugPrint('设备名称为空，使用默认设备名: $_deviceModel');
      }

      // 解析并创建目录结构
      int directoryId = 0; // 默认为根目录
      try {
        // 解析文件路径获取目录结构
        debugPrint('尝试解析文件路径以创建目录结构，设备名: $_deviceModel');
        directoryId = await _directoryPathParser.parseAndCreateDirectory(
          filePath,
          _deviceModel,
        );
        debugPrint('文件将上传到目录ID: $directoryId');
      } catch (e) {
        debugPrint('创建目录结构失败: $e，将使用默认目录');
      }

      // 创建上传任务配置
      final config = UploadTaskConfig(
        token: '',
        deviceModel: _deviceModel,
        enableChunk: true,
        chunkSize: UploadConfig.chunkSize, // 使用配置中的分片大小（5MB）
        parallelChunks: 2, // 增加并行上传分片数量
        albumName: _currentAlbumName, // 添加相册名称信息
        optimizeMemory: true, // 启用内存优化
        directoryId: directoryId, // 使用解析和创建的目录ID
      );

      // 判断是否为大文件
      final isLargeFile = file.lengthSync() > UploadConfig.largeFileThreshold;
      final uploadType = isLargeFile ? "分片上传" : "普通上传";
      final formattedFileSize = (file.lengthSync() / (1024 * 1024))
          .toStringAsFixed(2);

      debugPrint('文件大小: $formattedFileSize MB，使用$uploadType方式');
      if (isLargeFile) {
        debugPrint(
          '分片大小: ${(UploadConfig.chunkSize / (1024 * 1024)).toStringAsFixed(2)} MB，预计分片数: ${(file.lengthSync() / UploadConfig.chunkSize).ceil()}',
        );
      }

      // 创建上传结果完成器
      final completer = Completer<bool>();

      // 使用增强的上传方法启动上传
      try {
        final taskId = await _chunkUploadService.uploadFileWithCallbacks(
          file.path,
          config,
          onProgress: (progress, speed) {
            // 更新上传速率并记录进度
            // progress现在是0-100范围的值，直接显示
            final percentProgress = progress.toStringAsFixed(1);
            debugPrint(
              '上传进度: $percentProgress%, 速度: ${formatUploadSpeed(speed)}',
            );
          },
          onComplete: (success, url) async {
            try {
              debugPrint('文件${success ? "上传成功" : "上传失败"}: ${file.path}');

              if (success && url != null) {
                debugPrint('上传结果URL: $url');

                // 上传成功，更新文件哈希缓存
                await _hashDeduplicationService.saveUploadedFileHash(file);

                // 从处理中文件集合移除并添加到已处理集合
                _processingFilePaths.remove(filePath);
                _processedFilePaths.add(filePath);

                // 触发资产处理完成回调
                if (onAssetProcessed != null) {
                  await onAssetProcessed(asset, true);
                }

                // 完成上传
                if (!completer.isCompleted) {
                  completer.complete(true);
                }
              } else {
                debugPrint('上传失败: ${file.path}');

                // 从处理中文件集合移除
                _processingFilePaths.remove(filePath);

                // 触发资产处理失败回调
                if (onAssetProcessed != null) {
                  await onAssetProcessed(asset, false);
                }

                // 完成上传，标记为失败
                if (!completer.isCompleted) {
                  completer.complete(false);
                }
              }
            } catch (callbackError) {
              debugPrint('上传完成回调处理出错: $callbackError');

              // 从处理中文件集合移除
              _processingFilePaths.remove(filePath);

              // 触发资产处理失败回调
              if (onAssetProcessed != null && !completer.isCompleted) {
                await onAssetProcessed(asset, false);
              }

              // 完成上传，标记为失败
              if (!completer.isCompleted) {
                completer.complete(false);
              }
            }
          },
        );

        // 重要：将任务ID与资产ID关联起来
        _taskToAssetMap[taskId] = asset.id;
        debugPrint('任务ID与资产ID关联: $taskId -> ${asset.id}');

        // 监控上传进度并计算速度
        _monitorUploadProgress(asset.id);

        // 等待上传完成，获取最终结果
        return await completer.future;
      } catch (uploadError) {
        debugPrint('启动上传任务失败: $uploadError');

        // 从处理中文件集合移除
        _processingFilePaths.remove(filePath);

        // 触发资产处理失败回调
        if (onAssetProcessed != null) {
          await onAssetProcessed(asset, false);
        }

        return false;
      }
    } catch (e) {
      // 处理特定类型的错误
      if (e.toString().contains('UNIQUE constraint failed')) {
        debugPrint('文件哈希记录已存在，忽略此错误并继续上传处理');
        // 尝试继续处理上传完成的回调
        if (onAssetProcessed != null) {
          await onAssetProcessed(asset, true);
        }
        return true;
      }

      debugPrint('上传资产时发生异常: $e');

      // 尝试从处理中文件集合移除
      try {
        final file = await asset.file;
        if (file != null) {
          _processingFilePaths.remove(file.path);
        }
      } catch (_) {}

      // 触发处理完成回调
      if (onAssetProcessed != null) {
        await onAssetProcessed(asset, false);
      }
      return false;
    }
  }

  /// 解析文件路径获取目录结构
  /// 例如：/storage/emulated/0/DCIM/Camera/image.jpg 将解析为 ['设备名', 'DCIM', 'Camera']
  List<String> _parseFilePathForDirectoryStructure(String filePath) {
    try {
      debugPrint('解析文件路径: $filePath');

      // 标准化路径分隔符
      final normalizedPath = filePath.replaceAll('\\', '/');

      // 分割路径
      final parts = normalizedPath.split('/');

      // 创建目录结构数组
      final List<String> directoryStructure = [];

      // 设备名称作为第一级目录
      if (_deviceModel.isNotEmpty) {
        directoryStructure.add(_deviceModel);
      } else {
        directoryStructure.add(Platform.isAndroid ? 'Android设备' : 'iOS设备');
      }

      // 提取关键路径部分
      // Android路径示例: /storage/emulated/0/DCIM/Camera/image.jpg
      // 我们主要关心DCIM, Camera等相册目录
      for (int i = 0; i < parts.length - 1; i++) {
        final part = parts[i];

        // 跳过空部分和常见的存储路径前缀
        if (part.isEmpty ||
            part == 'storage' ||
            part == 'emulated' ||
            part == '0' ||
            part == 'data' ||
            part == 'media') {
          continue;
        }

        // 添加有意义的目录部分
        if ([
              'DCIM',
              'Pictures',
              'Camera',
              'Screenshots',
              'Download',
            ].contains(part) ||
            !['Android', 'iOS'].contains(part)) {
          directoryStructure.add(part);
        }
      }

      debugPrint('解析的目录结构: $directoryStructure');
      return directoryStructure;
    } catch (e) {
      debugPrint('解析文件路径失败: $e');
      return [_deviceModel]; // 失败时至少返回设备名作为目录
    }
  }

  /// 创建目录结构并返回最终目录ID
  Future<int> _createDirectoryStructure(List<String> directoryStructure) async {
    if (directoryStructure.isEmpty) {
      debugPrint('目录结构为空，返回根目录ID (0)');
      return 0; // 根目录
    }

    try {
      int directoryId = 0; // 从根目录开始
      String deviceName = directoryStructure[0]; // 第一级目录是设备名

      // 确保设备目录存在
      directoryId = await _directoryCacheService.getOrCreateDeviceDirectory(
        deviceName,
      );

      // 如果只有设备名一级目录，直接返回
      if (directoryStructure.length == 1) {
        debugPrint('只有设备名目录，返回设备目录ID: $directoryId');
        return directoryId;
      }

      // 处理二级目录（如DCIM）
      String secondLevelDirName = directoryStructure[1];
      directoryId = await _directoryCacheService.getOrCreateAlbumDirectory(
        deviceName,
        secondLevelDirName,
      );

      // 处理更深层次的目录结构（如Camera等）
      for (int i = 2; i < directoryStructure.length; i++) {
        final parentAlbumName = directoryStructure[i - 1];
        final albumName = directoryStructure[i];

        directoryId = await _directoryCacheService.getOrCreateSubAlbumDirectory(
          deviceName,
          parentAlbumName,
          albumName,
        );
      }

      debugPrint('创建目录结构完成，最终目录ID: $directoryId');
      return directoryId;
    } catch (e) {
      debugPrint('创建目录结构失败: $e');
      return 0; // 失败时返回根目录ID
    }
  }

  /// 清理所有备份相关的数据库和缓存
  Future<void> cleanupBackupData() async {
    debugPrint('开始清理所有备份相关的数据...');

    try {
      // 重置当前上传状态
      _isBackingUp = false;
      _currentParallelUploads = 0;
      _processingAssets.clear();
      _processingFilePaths.clear();
      _processedFilePaths.clear();
      _uploadQueue.clear();
      _taskToAssetMap.clear();
      _uploadSpeeds.clear();
      _uploadStartTimes.clear();

      // 重置当前相册状态
      _resetCurrentAlbumState();

      // 清理上传进度记录
      await _progressService.deleteAllProgress();
      debugPrint('已清理所有上传进度记录');

      // 关闭并重新初始化多层去重服务
      await _hashDeduplicationService.close();
      await _hashDeduplicationService.initialize(forceReset: true);
      debugPrint('已重置文件哈希去重服务');

      // 清理第一层去重缓存
      await _firstLayerDeduplicationService.clearCache();
      debugPrint('已清理第一层去重缓存');

      // 清理资产缓存
      _assetCacheService.clearCache();
      debugPrint('已清理资产缓存');

      // 清理目录缓存
      _directoryCacheService.clearCache();
      debugPrint('已清理目录缓存');

      // 取消所有上传任务
      ChunkUploadService.cancelAllTasks();
      debugPrint('已取消所有上传任务');

      debugPrint('已完成所有备份数据清理');
    } catch (e) {
      debugPrint('清理备份数据时出错: $e');
      rethrow;
    }
  }

  /// 检查API配置，仅用于调试
  Future<Map<String, dynamic>> checkApiConfig() async {
    try {
      // 获取API服务器URL
      final apiUrl = AppConfig.apiServerUrl;
      debugPrint('上传API地址: $apiUrl');

      // 获取API配置
      final config = AppConfig.apiConfig;

      // 检查是否使用自定义设置
      final userConfig = ConfigLoader().userConfig;

      // 创建包含关键信息的结果
      final result = {
        'apiUrl': apiUrl,
        'protocol': config['protocol'],
        'host': config['host'],
        'port': config['port'],
        'path_prefix': config['path_prefix'],
        'environment': AppConfig.environment,
        'isCustom': userConfig.isEnabled,
      };

      // 打印信息
      debugPrint('API配置: $result');

      // 检查是否可以连接到API服务器
      try {
        final client = http.Client();
        final healthUri = Uri.parse('$apiUrl/health');
        debugPrint('检查API健康状态: $healthUri');

        final response = await client
            .get(healthUri)
            .timeout(const Duration(seconds: 5));

        result['canConnect'] = response.statusCode == 200;
        result['statusCode'] = response.statusCode;
        result['response'] =
            response.body.length > 100
                ? '${response.body.substring(0, 100)}...'
                : response.body;

        debugPrint('API连接测试: ${result['canConnect']}');
      } catch (e) {
        result['canConnect'] = false;
        result['error'] = e.toString();
        debugPrint('API连接测试失败: $e');
      }

      return result;
    } catch (e) {
      debugPrint('检查API配置时出错: $e');
      return {'error': e.toString()};
    }
  }

  /// 仅重置文件哈希缓存，保留其他设置
  Future<void> resetFileHashCache() async {
    debugPrint('开始重置文件哈希缓存...');

    try {
      // 关闭并重新初始化多层去重服务
      await _hashDeduplicationService.close();

      // 清除哈希数据库中的所有记录
      await _hashDeduplicationService.clearAllHashRecords();

      // 重新初始化哈希去重服务
      await _hashDeduplicationService.initialize(forceReset: true);
      debugPrint('已重置文件哈希去重服务');

      // 清理第一层去重缓存
      await _firstLayerDeduplicationService.clearCache();
      debugPrint('已清理第一层去重缓存');

      // 清理处理过的文件路径缓存
      _processingFilePaths.clear();
      _processedFilePaths.clear();
      debugPrint('已清理处理过的文件路径缓存');

      debugPrint('文件哈希缓存重置完成');
    } catch (e) {
      debugPrint('重置文件哈希缓存时出错: $e');
      rethrow;
    }
  }

  // 创建并启动上传任务
  Future<String> _startFileUpload(File file, UploadTaskConfig config) async {
    debugPrint('准备上传文件: ${file.path}');
    debugPrint('上传配置: $config');

    // 检查API服务器URL是否正确
    final apiUrl = AppConfig.apiServerUrl;
    debugPrint('上传API地址: $apiUrl');

    try {
      // 检查文件是否存在
      if (!await file.exists()) {
        debugPrint('文件不存在: ${file.path}');
        throw Exception('文件不存在');
      }

      // 获取文件大小
      final fileSize = await file.length();
      debugPrint('文件大小: $fileSize 字节');

      // 记录上传开始
      debugPrint('开始上传文件，调用上传服务...');

      // 为任务生成临时ID，用于日志记录
      final tempTaskId = DateTime.now().millisecondsSinceEpoch.toString();

      // 创建上传完成的Completer
      final completer = Completer<(bool, String?)>();

      // 实际启动上传，并传递回调处理
      final taskId = await _chunkUploadService.uploadFileWithCallbacks(
        file.path,
        config,
        onProgress: (progress, speed) {
          // 更新上传速率并记录进度
          // progress应该是0-100范围的值，直接显示
          final percentProgress = progress.toStringAsFixed(1);
          debugPrint(
            '上传进度: $percentProgress%, 速度: ${formatUploadSpeed(speed)}',
          );
        },
        onComplete: (success, url) async {
          if (success) {
            debugPrint('文件上传成功: ${file.path}');
            debugPrint('上传结果URL: $url');

            // 查找关联的资产ID
            String? assetId = _taskToAssetMap[tempTaskId];
            if (assetId != null) {
              debugPrint('上传成功的文件关联资产ID: $assetId');
            }

            // 完成Completer，返回成功状态和URL
            completer.complete((true, url));
          } else {
            debugPrint('文件上传失败: ${file.path}');

            // 完成Completer，返回失败状态
            completer.complete((false, null));
          }
        },
      );

      debugPrint('上传任务已创建，任务ID: $taskId');

      // 同步在映射中保存任务ID
      if (_taskToAssetMap.containsKey(tempTaskId)) {
        _taskToAssetMap[taskId] = _taskToAssetMap[tempTaskId]!;
      }

      return taskId;
    } catch (e) {
      debugPrint('创建上传任务失败: $e');
      rethrow;
    }
  }

  /// 开始备份相册
  Future<void> startBackup(String deviceName) async {
    if (_isBackingUp) {
      debugPrint('已有备份任务正在进行中');
      return;
    }

    _isBackingUp = true;
    debugPrint('开始备份相册，设备名称: $deviceName');

    try {
      // 获取所有相册
      final albums = await PhotoManager.getAssetPathList(
        type: RequestType.common,
      );
      debugPrint('获取到 ${albums.length} 个相册');

      for (var album in albums) {
        if (!_isBackingUp) {
          debugPrint('备份任务已停止');
          break;
        }

        debugPrint('处理相册: ${album.name}');
        final assets = await album.getAssetListRange(start: 0, end: 100000);
        debugPrint('相册 ${album.name} 包含 ${assets.length} 个文件');

        for (var asset in assets) {
          if (!_isBackingUp) {
            debugPrint('备份任务已停止');
            break;
          }

          if (_processingAssets.contains(asset.id)) {
            debugPrint('文件 ${asset.title} 正在处理中，跳过');
            continue;
          }

          _processingAssets.add(asset.id);
          _updateAssetStatus(asset, AssetBackupStatus.uploading);

          try {
            // 获取文件路径
            final file = await asset.file;
            if (file == null) {
              throw Exception('无法获取文件');
            }

            // 解析并创建目录结构
            final directoryId = await _directoryPathParser
                .parseAndCreateDirectory(file.path, deviceName);

            debugPrint('文件 ${asset.title} 将上传到目录ID: $directoryId');

            // 上传文件
            await _uploadTaskManager.uploadFile(
              file: file,
              filename: asset.title ?? 'unknown',
              directoryId: directoryId,
              onProgress: (progress) {
                _updateAssetProgress(asset, progress);
              },
            );

            _updateAssetStatus(asset, AssetBackupStatus.completed);
          } catch (e) {
            debugPrint('处理文件 ${asset.title} 失败: $e');
            _updateAssetStatus(asset, AssetBackupStatus.failed);
          } finally {
            _processingAssets.remove(asset.id);
          }
        }
      }
    } catch (e) {
      debugPrint('备份过程出错: $e');
    } finally {
      _isBackingUp = false;
    }
  }

  /// 停止备份
  void stopBackup() {
    _isBackingUp = false;
    debugPrint('停止备份任务');
  }
}

/// 相册资产处理器 - 基于事件的资产获取和处理机制
class AlbumAssetsProcessor {
  final FileHashDeduplicationService _hashDeduplicationService;
  final UploadProgressService _progressService;
  final Set<String> _processingAssets;

  // 事件回调
  Function(List<AssetEntity>)? onBatchLoaded;
  Function(List<AssetEntity>)? onNonDuplicatesFound;
  Function(String, int, int)? onProgressUpdated;
  Function(String)? onAlbumCompleted;
  Function(Exception)? onError;

  AlbumAssetsProcessor(
    this._hashDeduplicationService,
    this._progressService,
    this._processingAssets,
  );

  /// 处理相册资产
  Future<List<AssetEntity>> processAlbumAssets({
    required AssetPathEntity album,
    required String albumName,
    required int startIndex,
    required bool includePhotos,
    required bool includeVideos,
    int batchSize = 20,
    int maxBatches = 5,
  }) async {
    try {
      final totalCount = await album.assetCountAsync;
      debugPrint('开始处理相册 $albumName - 起始位置: $startIndex, 总数: $totalCount');

      // 如果已经处理完所有资产
      if (startIndex >= totalCount) {
        debugPrint('相册 $albumName 已处理完所有资产');
        if (onAlbumCompleted != null) {
          onAlbumCompleted!(album.id);
        }
        await _progressService.markAlbumCompleted(album.id);
        return [];
      }

      // 计算要获取的资产数量，不超过剩余资产数量
      final fetchCount = math.min(
        batchSize * maxBatches,
        totalCount - startIndex,
      );
      debugPrint('从相册 $albumName 一次性获取 $fetchCount 个资产，从索引 $startIndex 开始');

      // 一次性获取所有需要的资产
      final assets = await album.getAssetListRange(
        start: startIndex,
        end: startIndex + fetchCount,
      );

      // 如果没有资产，说明已到达相册末尾
      if (assets.isEmpty) {
        debugPrint('相册 $albumName 已到达末尾');
        if (onAlbumCompleted != null) {
          onAlbumCompleted!(album.id);
        }
        await _progressService.markAlbumCompleted(album.id);
        return [];
      }

      // 触发批次加载事件
      if (onBatchLoaded != null) {
        onBatchLoaded!(assets);
      }

      // 根据设置过滤照片和视频
      final filteredAssets =
          assets.where((asset) {
            if (asset.type == AssetType.image) {
              return includePhotos;
            } else if (asset.type == AssetType.video) {
              return includeVideos;
            }
            return false;
          }).toList();

      debugPrint('相册 $albumName 过滤后剩余 ${filteredAssets.length} 个资产');

      // 过滤掉已经在处理中的资产
      final newAssets =
          filteredAssets
              .where((asset) => !_processingAssets.contains(asset.id))
              .toList();

      // 应用去重逻辑
      debugPrint('对 ${newAssets.length} 个资产执行去重过滤');
      final nonDuplicates = await _hashDeduplicationService
          .filterDuplicateAssets(newAssets);
      debugPrint('去重后剩余 ${nonDuplicates.length} 个资产需要上传');

      // 触发非重复资产发现事件
      if (onNonDuplicatesFound != null && nonDuplicates.isNotEmpty) {
        onNonDuplicatesFound!(nonDuplicates);
      }

      // 更新进度
      await _progressService.updateAlbumProgress(
        albumId: album.id,
        albumName: albumName,
        processedCount: startIndex + assets.length,
        lastAssetId: assets.isNotEmpty ? assets.last.id : null,
      );

      // 触发进度更新事件
      if (onProgressUpdated != null) {
        onProgressUpdated!(album.id, startIndex + assets.length, totalCount);
      }

      // 检查是否已处理完相册
      if (startIndex + assets.length >= totalCount) {
        debugPrint('相册 $albumName 已处理完所有资产');
        if (onAlbumCompleted != null) {
          onAlbumCompleted!(album.id);
        }
        await _progressService.markAlbumCompleted(album.id);
      }

      return nonDuplicates;
    } catch (e) {
      debugPrint('处理相册 $albumName 资产时出错: $e');
      if (onError != null) {
        onError!(e is Exception ? e : Exception(e.toString()));
      }
      return [];
    }
  }
}
